Article = require('../models/article').Article
Dict = require('../models/dict').Dict
dataPage = require('../services/dataPage').queryPage
dataPage2 = require('../services/dataPage').queryPage2
resErr = require('./util').resErr
util = require("util")
ObjectID = require('mongodb').ObjectID
mongooseObjectId = require('mongoose').Types.ObjectId
_ = require('underscore')
file_util = require('../services/file_util')
gridfs = new (require('../services/gridfs').FileStoreService)(require('../config').fsdb.db)
async = require('async')
request = require('request')
moment = require('moment')
S = require('string')


exports.article_test = (req,res) ->
  file_id = req.param("file_id")
  gridfs_id = require('mongoose').Types.ObjectId(file_id)
  console.log gridfs_id
  # file_util.delete_by_file_id file_id,(err) ->
  #   return resErr res,err if err
  #   return res.json({'success':true})
  gridfs.deleteFile gridfs_id,(err) ->
    return resErr res,err if err
    return res.json({'success':true})

exports.article_add = (req,res) ->
  code = req.param('code')
  type_names = []
  type_name = ''
  async.waterfall [
    (cbk) ->
      paths = req.param("type_path").split('/')
      async.eachSeries paths,(path, callback) ->
        if path.length > 0 and path != 'root'
          Dict.findOne({"key_code":path}).sort(null).exec (err,dict) ->
            if err
              return callback err
            else
              type_names.push dict.key_name
              return callback null
        else if path == 'root'
          type_names.push 'root'
          return callback null
        else
          return callback null
      ,(err) ->
        return cbk err if err
        type_name = type_names.join '/' 
        return cbk null
    (cbk) ->
      if code
        Article.findOne {code:req.param('code')},(err,result) ->
          return resErr res,err if err
          return resErr res,'code已经存在!' if result
          article = new Article
          article.add req,type_name,(err)->
            return cbk err if err
            return cbk null
      else
        article = new Article
        article.add req,type_name,(err)->
          return cbk err if err
          return cbk null
  ],(error) ->
    return resErr res, error if error
    return res.json({'success':'true'})

exports.article_add_attach = (req,res) ->
  file_name = req.param("file_name")
  file_id = req.param("file_id")
  file_size = req.param("file_size")
  _id = req.param('_id')
  if !_id || !file_name || !file_id
    return resErr(res,"_id或file_name或file_id不的为空！")
  Article.findById _id,(err,article)->
    return resErr res,err if err
    file = {}
    file.file_id = file_id
    file.file_name = file_name
    file.file_size = file_size
    file.upload_date = new Date
    article.markModified('array')
    article.file_list.push file
    article.save (err)->
      resErr res,err if err
      res.json {"success":true}

exports.article_del_attach = (req,res) ->
  _id = req.param("_id")
  file_id = req.param("file_id")
  if !_id || !file_id
    return resErr "_id或file_id不的为空！"
  Article.findById _id,(err,article) ->
    return resErr res,err if err
    for i of article.file_list
      if article.file_list[i].file_id.toString() == file_id
        article.file_list.splice(i,1)
        break
    article.markModified('array')
    article.save (err)->
      resErr res,err if err
      gridfs_id = require('mongoose').Types.ObjectId(file_id)
      gridfs.deleteFile gridfs_id,(err) ->
        return resErr res,err if err
        return res.json({'success':true})

exports.article_list = (req,res) ->
  params = {}
  #相当于sql里面like的写法
  params.title = {'$regex': req.param("title")}  unless !req.param("title")
  # params.type = {'$regex': req.param("type")}  unless !req.param("type")
  params.type = req.param("type") unless !req.param("type")
  params.code = {'$regex': req.param("code")}  unless !req.param("code")
  params.type_path = {'$regex': req.param("type_path")}  unless !req.param("type_path")
  #today = new Date().toFormat('YYYYMMDD')
  #params.begin_date = {'$lte': today}
  #params.end_date = {'$gte': today}
  sorts = {}  
  fields = {}
  sort = req.param('sort')
  dir = req.param('dir')

  if dir && sort
    dir = if dir.toUpperCase() == 'ASC' then 1 else -1
    sorts[sort] = dir
  else
    sorts["priority"] = -1
    sorts["updated_at"] = -1
  fields.content = false unless !req.param("fields")
  dataPage2 Article,params,fields,sorts,req.param("pageSize") or req.param("limit"),req.param("pageNum") or req.param("page"), (err,results) ->
    if err
      resErr(res,err)
    else
      res.json(results)

exports.article_listby_code = (req,res) ->
  code = req.param("code")
  Article.findOne {code:req.param('code')},(err,result) ->
    return resErr res,err if err
    return res.json result

exports.article_del = (req,res) ->
  if !req.param('_id')
    resErr(res,'编码不得为空')
  else
    _id = req.param('_id')
    Article.findByIdAndRemove _id,(err,article)->
      console.log(article)
      return resErr res,err if err
      async.each article.file_list,(file,callback)->
        gridfs_id = require('mongoose').Types.ObjectId(file.file_id)
        gridfs.deleteFile gridfs_id,(err)->
          return callback err if err
          return callback null
      ,(err) ->
        return resErr res,err if err
        res.json({'success':true})      

exports.article_detail = (req,res) ->
  _id = req.param('_id')
  if !_id
    res.json({'success':'false','err_msg':'编码不得为空'})
  else
    Article.findById _id, (err,result) ->
      if err
        resErr(res,err)
      else
        res.json(result)

exports.article_edit = (req,res) ->
  _id = req.param('_id')
  if !_id
    res.json({'success':false,'err_msg':'编码不得为空'})
  params = {}
  params.summary = req.param("summary")
  params.title = req.param("title")
  params.begin_date = req.param("begin_date")
  params.end_date = req.param("end_date")
  params.sorder = req.param("sorder")
  params.type = req.param("type")
  params.type_path = req.param("type_path")
  params.content = req.param("content")
  params.content_strip = S(params.content).stripTags().s if params.content
  params.author = req.param("author")
  params.updated_at = new Date
  params.priority = req.param('priority') || 0
  params.code = req.param('code')
  params.target = req.param('target')
  params._url = req.param('_url')
  params.image_page_title_id = req.param('image_page_title_id')
  params.ex1 = req.param('ex1') || ''
  params.ex2 = req.param('ex2') || ''
  params.ex3 = req.param('ex3') || ''
  params.ex4 = req.param('ex4') || ''
  type_names = []
  type_name = ''
  async.waterfall [
    (cbk) ->
      paths = req.param("type_path").split('/')
      async.eachSeries paths,(path, callback) ->
        if path.length > 0 and path != 'root'
          Dict.findOne({"key_code":path}).sort(null).exec (err,dict) ->
            if err
              return callback err
            else
              type_names.push dict.key_name
              return callback null
        else if path == 'root'
          type_names.push 'root'
          return callback null
        else
          return callback null
      ,(err) ->
        return cbk err if err
        params.type_name = type_names.join '/' 
        return cbk null
    (cbk) ->
      if params.code
        Article.findOne {code:req.param('code'),_id:{$ne:new ObjectID(_id)}},(err,result) ->
          return cbk err if err
          return cbk 'code已经存在!' if result
          Article.findByIdAndUpdate _id,params,(err) ->
            return cbk err if err
            return cbk null
      else
        Article.findByIdAndUpdate _id,params,(err) ->
          return cbk err if err
          return cbk null
  ],(error) ->
    return resErr res, error if error
    return res.json({'success':'true'})

exports.article_web_list = (req,res) ->
  whichCat = req.param("whichCat")
  if !whichCat
    return res.json({'success':false,'err_msg':'whichCat（栏目编码）不能为空！'})
  params = {}
  #相当于sql里面like的写法
  params.title = {'$regex': req.param("title")}  unless !req.param("title")
  params.type = {"$in": whichCat.split(",")}
  #console.log params
  sorts = {}  
  fields = {}
  sort = req.param('sort')
  dir = req.param('dir')
  if dir && sort
    dir = if dir.toUpperCase() == 'ASC' then 1 else -1
    sorts[sort] = dir
    sorts["updated_at"] = -1
  else
    #默认按资讯开始日期降序，再按更新日期降序
    sorts["begin_date"] = -1
    sorts["updated_at"] = -1
  fields["content_strip"] = 1
  fields["title"] = 1
  fields["image_page_title_id"] = 1
  fields["begin_date"] = 1
  fields["type"] = 1
  fields["type_name"] = 1
  fields["type_path"] = 1
  dataPage2 Article,params,fields,sorts,req.param("pageSize"),req.param("pageNum"), (err,results) ->
    if err
      resErr res, err
    else
      res.json results

#获取指定栏目下除本栏目之外的推荐阅读资讯
exports.article_web_command = (req, res) ->
  whichCat = req.param("whichCat")
  if !whichCat
    return res.json({'success':false,'err_msg':'whichCat（栏目编码）不能为空！'})
  params = {}
  #包含
  #params.type = {"$in": whichCat.split(",")}
  #不包含
  types = []
  parent_code = null
  cats = []
  param_cats = []
  types = whichCat.split(",")
  if types.length > 1
    return resErr res, 'whichCat不能含有多个栏目！'
  #获取当前栏目的同级栏目
  async.waterfall [
    (cb) ->
      Dict.findOne({"key_code":whichCat}).sort(null).exec (err,dict) ->
        if err
          return cb err
        else
          parent_code = dict.parent_code
          return cb null
    (cb) ->
      Dict.find({"parent_code":parent_code}).sort(null).exec (err,dicts) ->
        if err
          return cb err
        else
          for d in dicts
            if d.key_code != whichCat
              cats.push d.key_code
              param_cats.push d.key_code
          return cb null
    (cb) ->
      if cats.length > 0
        async.eachSeries cats, (key_code, callback) ->
          Dict.find({"parent_code":key_code}).sort(null).exec (err,dicts) ->
            if err
              return callback err
            else
              for d in dicts
                param_cats.push d.key_code
              return callback null
        ,(err) ->
          return cb err if err
          return cb null
      else
        return cb null
    (cb) ->
      params.type = {"$in": param_cats}
      sorts = {}
      fields = {}
      sorts["begin_date"] = -1
      fields["title"] = 1
      fields["content_strip"] = 1
      fields["image_page_title_id"] = 1
      fields["begin_date"] = 1
      fields["type"] = 1
      fields["type_name"] = 1
      fields["type_path"] = 1
      Article.find(params, fields).sort(sorts).limit(req.param("pageSize") || 2).exec (err,data) ->
        return cb err if err
        return res.json data
  ],(error) ->
    return resErr res, error if error

getConfig = () -> 
  env = process.env.NODE_ENV || 'development'
  config = services.environment[env] 
  return config 

#导入老广发网指定栏目资讯到本地的对应栏目
exports.aritcle_import = (req, res) ->
  gridfs_id = new mongooseObjectId()
  config = getConfig()
  category = req.param('category')     #新广发网的栏目 type字段
  type_path = req.param('type_path')   #新广发网栏目业务编码层级
  gf_category = req.param('gf_category')   #广发网上的 type 字段
  target = '_blank'
  sorder = '0'
  priority = 0
  begin_date = moment(new Date()).format('YYYYMMDD')
  end_date = 29990101
  return resErr(res, '同步品类不能为空!') if !category || !gf_category
  url = config.old_gf_host+config.old_gf_url['message']+'?catName='+gf_category
  attachUrl = config.old_gf_host+config.old_gf_url['attachfile']
  type_names = []
  type_name = ''
  async.waterfall [
    (cbk) ->
      #获取栏目层级名称
      paths = type_path.split('/')
      async.eachSeries paths,(path, callback) ->
        if path.length > 0 and path != 'root'
          Dict.findOne({"key_code":path}).sort(null).exec (err,dict) ->
            if err
              return callback err
            else
              type_names.push dict.key_name
              return callback null
        else if path == 'root'
          type_names.push 'root'
          return callback null
        else
          return callback null
      ,(err) ->
        return cbk err if err
        type_name = type_names.join '/' 
        return cbk null
    (cbk) ->
      console.log '开始请求:'+url+' ...'
      request url,(error, response, body) ->
        if !error && response.statusCode == 200 
          responseData = JSON.parse(body)
          console.log '待同步的数据：'+responseData.length
          #循环调用获取资讯的详情
          if responseData && responseData.length > 0
            async.eachSeries responseData,(message,callback) ->
              console.log message.title
              doc_id = message.doc_id
              article = {}
              article.doc_id = doc_id
              article.title = message.title
              article.author = message.author || '广发证券'
              article.type = category
              article.type_path = type_path
              article.type_name = type_name
              article.target = target
              begin_date =  moment(message.source_date).format('YYYYMMDD') if message.source_date #来源时间
              article.begin_date = begin_date
              article.end_date = end_date
              article.sorder = sorder
              article.content = message.content
              article.content_strip = S(message.content).stripTags().s if message.content
              article.priority = priority
              article.updated_at = moment(message.modify_date)
              async_pro_flg = false
              _id = ''
              attachlist = message.attach_list
              old_attachlist = []
              return callback null if !article.doc_id
              async.waterfall [
                (cb) ->
                  content = article.content
                  content_url = config.old_gfw+content
                  #console.log 'content length: '+content.length
                  if content.length == 36
                    article.content = "请点击"+"<a href='"+content_url+"' target='_blank'><font color='blue'>"+article.title+"</font>打开或下载</a>"
                    article.content_strip = S(article.content).stripTags().s
                    return cb null
                  else 
                    return cb null
                (cb) ->
                  Article.findOne {doc_id:doc_id},(err,result) ->
                    if err
                      return cb err
                    unless result
                      return cb null               
                    async_pro_flg = true
                    _id = result._id  
                    old_attachlist = result.file_list               
                    #console.log('本地已存在相同资讯 '+doc_id)
                    return cb null
                (cb) ->
                  #处理附件，存在附件，则逐个添加，然后删除旧的
                  if attachlist && attachlist.length>0
                    console.log 'proccess attachlist' 
                    async.waterfall [
                      (cb) ->
                        #删除旧附件
                        async.eachSeries old_attachlist,(old_attach,old_attachCallback) ->
                          gridfs_id = require('mongoose').Types.ObjectId(old_attach.file_id)
                          console.log 'delete old attachlist '+gridfs_id
                          gridfs.deleteFile gridfs_id,(err) ->
                            #return old_attachCallback err if err
                            return old_attachCallback null
                        ,(err) ->
                          return cb err if err  
                          return cb null
                      (cb) ->    
                        #添加新附件
                        new_attachlist = []
                        async.eachSeries attachlist,(attach,attachCallback) ->               
                          fileUrl = attachUrl+attach.fileId
                          fileName = attach.fileName
                          console.log '有新附件:'+fileName+' '+'fileUrl='+fileUrl
                          getAttachByWeb fileUrl,fileName, (error,result) ->
                            #return attachCallback error if error
                            #console.log 'result.file_id = '+result.file_id
                            new_attachlist.push result
                            return attachCallback null 
                        ,(err) ->
                          return cb err if err
                          article.file_list = new_attachlist
                          cb null               
                    ],(err) ->
                      return cb err if err
                      return cb null              
                  else
                    cb null
                (cb) ->
                  #资讯已存在
                  if async_pro_flg
                      Article.findByIdAndUpdate _id,article,(err) ->
                        return cb err if err
                        console.log '资讯修改成功: doc_id='+doc_id
                        return cb null
                  #资讯不存在，添加新资讯
                  else
                    new_article = new Article()
                    new_article.addByParam article,(err)->
                      return cb err if err
                      console.log '资讯添加成功: doc_id='+doc_id
                      return cb null
              ],(err) ->
                #return resErr(res,err) if err
                #return callback(null)
                return callback err if err
                return callback null
            ,(err) ->
              return cbk err if err
              console.log('资讯同步已全部完成！')
              #return res.json ({'success':true, 'msg':'资讯同步已全部完成！'})
              return cbk {'success':true, 'msg':'资讯同步已全部完成！'}
          else
            #return res.json ({'success':false, 'msg':'无资讯可同步！'})
            return cbk {'success':false, 'msg':'无资讯可同步！'}
        else
          #return resErr(res, '老广发同步接口访问异常，获取资讯信息错误!')
          return cbk {'success':false, 'msg':'老广发同步接口访问异常，获取资讯信息错误!'}
  ],(message) ->
    return res.json message  

getAttachByWeb = (attachUrl,attachName,callback) ->
  gridfs_id = new mongooseObjectId()
  config = getConfig()
  url = attachUrl
  result = {}
  filename = attachName
  requestParam = {}
  requestParam.url = url
  requestParam.encoding = null
  filetype = ''
  uploadFile = {}
  async.waterfall [
    (cb) ->
      #获取文件
      request requestParam,(err,response,body)->
        if !err && response.statusCode == 200 
          console.log '附件请求成功...'+body.length+'-'+body.type+'-'+body.name
          data = body
          gridfs.uploadFileByData gridfs_id, filename ,data, filetype, (err) ->
            #console.log '保存成功1111'
            if err
              return cb err
            else         
              #console.log '附件保存成功2222...'
              uploadFile.file_id = gridfs_id
              uploadFile.file_name = filename
              uploadFile.file_size = data.length
              uploadFile.upload_date = new Date
              return cb null
        else
          console.log '附件请求失败...'
          return cb err
  ],(error) ->
    console.log JSON.stringify uploadFile
    return callback(error,uploadFile)